package auctionsimulation.market;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Timer;

import auctionsimulation.agent.Agent;
import auctionsimulation.statistics.Statistics;

public abstract class Auction implements Serializable {

	private static final long serialVersionUID = -14414465038461947L;

	private long UUID;
	private Agent initiator;
	protected HashMap<String, Long> productTemplate;
	protected boolean started;
	protected boolean finished;
	protected boolean successfull;
	protected AuctionTimer timer;

	public Auction(Agent initiator, HashMap<String, Long> productTemplate) {
		this.UUID = java.util.UUID.randomUUID().getMostSignificantBits();
		this.initiator = initiator;
		this.productTemplate = productTemplate;
		if (initiator == null)
			throw new IllegalAuctionException("initiator must not be null");
		if (productTemplate == null)
			throw new IllegalAuctionException(
					"productTemplate must not be null");
		this.started = false;
		this.finished = false;
		this.successfull = false;
		this.timer = new AuctionTimer();
	}

	public long getUUID() {
		return this.UUID;
	}

	public Agent getInitiator() {
		return this.initiator;
	}

	public HashMap<String, Long> getProductTemplate() {
		return this.productTemplate;
	}

	public boolean isFinished() {
		return this.finished;
	}

	public boolean wasSuccessfull() {
		return this.successfull;
	}

	public abstract void start();

	protected boolean matchTemplate(HashMap<String, Long> requireTemplate) {

		if (requireTemplate.size() != this.productTemplate.size()) {
			return false;
		}

		for (Entry<String, Long> requireEntry : requireTemplate.entrySet()) {
			Long requireValue = requireEntry.getValue();
			Long productValue = productTemplate.get(requireEntry.getKey());
			if (requireValue == null || productValue == null) {
				return false;
			}
			if (productValue < requireValue) {
				return false;
			}
		}
		return true;
	}

	protected boolean checkNewOfferTemplateBetter(
			HashMap<String, Long> offeredTemplate) {
		if (offeredTemplate.size() != this.productTemplate.size()) {
			return false;
		}

		for (Entry<String, Long> offerEntry : offeredTemplate.entrySet()) {
			Long offerValue = offerEntry.getValue();
			Long productValue = productTemplate.get(offerEntry.getKey());
			if (offerValue == null || productValue == null) {
				return false;
			}
			if (productValue > offerValue) {
				return false;
			}
		}
		return true;
	}

	public abstract double getCurrentPrice();

	protected class AuctionTimer extends Timer implements Serializable {

		private static final long serialVersionUID = -2924614224895153328L;
	};

}
